/*
 * Copyright (c) 2009 LastFM.Desktop Anton Pavlik.
 * All Rights Reserved.
 * 
 * You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, 
 * with or without modifications, and in Source or Object form, provided that You meet the following 
 * conditions:
 * 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
 *
 * 2. You must cause any modified files to carry prominent notices stating that You changed the files; 
 * and
 *
 * 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, 
 * patent, trademark, and attribution notices from the Source form of the Work, excluding those notices 
 * that do not pertain to any part of the Derivative Works.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * You may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 *
 * Unless required by applicable law or agreed to in writing, Licensor provides the Work 
 * (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
 * CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties 
 * or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. 
 * YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USING OR REDISTRIBUTING THE WORK
 * AND ASSUME ANY RISKS ASSOCIATED WITH YOUR EXERCISE OF PERMISSIONS UNDER THIS LICENSE. 
 */
package org.shake.lastfm.ui.info.pages.track;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextPane;
import javax.swing.SwingWorker;
import javax.swing.UIManager;

import org.bushe.swing.event.annotation.AnnotationProcessor;
import org.bushe.swing.event.annotation.EventTopicSubscriber;
import org.jdesktop.swingx.JXPanel;
import org.shake.lastfm.api.XmlRpcApi;
import org.shake.lastfm.api.XmlRpcApiImpl;
import org.shake.lastfm.event.EventTopic;
import org.shake.lastfm.event.TrackSelectedEvent;
import org.shake.lastfm.model.Album;
import org.shake.lastfm.model.Artist;
import org.shake.lastfm.model.Track;
import org.shake.lastfm.ui.artist.ArtistPicturesPanel;

public class TrackPage extends JXPanel
{
    private static final long serialVersionUID = 2231946188626411014L;
    
    private JTextPane artistSummaryArea;
    private JTextPane albumSummaryArea;

    private SwingWorker<Artist, Void> artistInfoFetcher;
    private SwingWorker<Album, Void> albumInfoFetcher;

    private Track selectedTrack;
    
    public TrackPage()
    {
        super();

        buildUI();
        AnnotationProcessor.process(this);
    }

    private void buildUI()
    {
        setLayout(new BorderLayout());
        
        TrackInfoPanel trackInfoPanel = new TrackInfoPanel();
        trackInfoPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
        
        JComponent compositePanel = buildCompositePanel();
        compositePanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));

        add(trackInfoPanel, BorderLayout.NORTH);
        add(compositePanel, BorderLayout.WEST);
        add(new ArtistPicturesPanel(), BorderLayout.CENTER);
    }
    
    private JComponent buildCompositePanel()
    {
        JTabbedPane result = new JTabbedPane();
        result.setTabPlacement(JTabbedPane.BOTTOM);
        result.addTab("artist", buildArtistPanel());
        result.addTab("album", buildAlbumPanel());
        return result;
    }
    
    private Component buildAlbumPanel()
    {
        BorderLayout layout = new BorderLayout();
        JXPanel result = new JXPanel(layout);
        
        this.albumSummaryArea = new JTextPane();
        this.albumSummaryArea.setEditable(false);
        this.albumSummaryArea.setContentType("text/html");
        this.albumSummaryArea.setBackground(getBackground());

        JScrollPane albumSp = new JScrollPane(this.albumSummaryArea);
        albumSp.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
        albumSp.setPreferredSize(new Dimension(200, 100));
        
        result.add(albumSp, BorderLayout.CENTER);
        return result;
    }

    private JComponent buildArtistPanel()
    {
        BorderLayout layout = new BorderLayout();
        JXPanel result = new JXPanel(layout);
        
        this.artistSummaryArea = new JTextPane();
        this.artistSummaryArea.setContentType("text/html");
        this.artistSummaryArea.setEditable(false);
        this.artistSummaryArea.setOpaque(false);
        this.artistSummaryArea.setBorder(BorderFactory.createEmptyBorder());
        this.artistSummaryArea.setBackground(UIManager.getColor("Label.background"));
        
        JScrollPane artistSp = new JScrollPane(this.artistSummaryArea);
        artistSp.setPreferredSize(new Dimension(200, 100));
        artistSp.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
        
        result.add(artistSp, BorderLayout.CENTER);
        
        return result;
    }
    
    @EventTopicSubscriber(topic=EventTopic.TRACK_SELECTED)
    public void onTrackSelectionChanged(String topic, TrackSelectedEvent event)
    {
        this.selectedTrack = event.getTrack();
        
        if (this.selectedTrack != null)
        {
            fetchArtistInfo(this.selectedTrack.getCreator());
            fetchAlbumInfo(this.selectedTrack.getCreator(), this.selectedTrack.getAlbum());
        }
    }
    
    private void fetchAlbumInfo(final String artistName, final String albumName)
    {
        if (this.albumInfoFetcher != null && !this.albumInfoFetcher.isDone())
        {
            this.albumInfoFetcher.cancel(true);
        }

        this.albumInfoFetcher = new SwingWorker<Album, Void>()
        {
            @Override
            protected Album doInBackground() throws Exception
            {
                XmlRpcApi api = new XmlRpcApiImpl();
                return api.fetchAlbumInfo(artistName, albumName);
            }

            @Override
            protected void done()
            {
                try
                {
                    Album album = get();
                    TrackPage.this.albumSummaryArea.setText(album == null ? "" : album.getSummary());
                    TrackPage.this.albumSummaryArea.setCaretPosition(0);
                } catch (Exception e)
                {
                    TrackPage.this.albumSummaryArea.setText("");
                    e.printStackTrace();
                }
            }
        };
        this.albumInfoFetcher.execute();
    }
    
    private void fetchArtistInfo(final String artistName)
    {
        if (this.artistInfoFetcher != null && !this.artistInfoFetcher.isDone())
        {
            this.artistInfoFetcher.cancel(true);
        }

        this.artistInfoFetcher = new SwingWorker<Artist, Void>()
        {
            @Override
            protected Artist doInBackground() throws Exception
            {
                XmlRpcApi api = new XmlRpcApiImpl();
                return api.fetchArtistInfo(artistName);
            }

            @Override
            protected void done()
            {
                try
                {
                    Artist artist = get();
                    TrackPage.this.artistSummaryArea.setText(artist == null ? "" : artist.getSummary());
                    TrackPage.this.artistSummaryArea.setCaretPosition(0);
                } catch (Exception e)
                {
                    TrackPage.this.artistSummaryArea.setText("");
                    e.printStackTrace();
                }
            }
        };
        
        this.artistInfoFetcher.execute();
    }
}